package com.PAT.UnSatisfying;

import java.util.*;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: zjz
 * @Date: 2022/01/31/23:28
 * @Description:PAT 准考证号由 4 部分组成：
 *
 * 第 1 位是级别，即 T 代表顶级；A 代表甲级；B 代表乙级；
 * 第 2~4 位是考场编号，范围从 101 到 999；
 * 第 5~10 位是考试日期，格式为年、月、日顺次各占 2 位；
 * 最后 11~13 位是考生编号，范围从 000 到 999。
 * 现给定一系列考生的准考证号和他们的成绩，请你按照要求输出各种统计信息。
 * @Target: 差9
 */
public class 解码PAT准考证{
    public static void main(String[] args) {

        /*
        *     输入格式：
            输入首先在一行中给出两个正整数 N（≤10^4）和 M（≤100），分别为考生人数和统计要求的个数。

            接下来 N 行，每行给出一个考生的准考证号和其分数（在区间 [0,100] 内的整数），其间以空格分隔。

            考生信息之后，再给出 M 行，每行给出一个统计要求，格式为：类型 指令，其中


            *

            *

            输出格式：
            对每项统计要求，首先在一行中输出 Case #: 要求，其中 # 是该项要求的编号，从 1 开始；要求 即复制输入给出的要求。随后输出相应的统计结果：

            类型 为 1 的指令，；
            类型 为 2 的指令，
            类型 为 3 的指令，
            如果查询结果为空，则输出 NA。
            * */

        // 输入开始
        Scanner in = new Scanner(System.in);
        String s1  = in.nextLine();
        String[] s = s1.split(" ");
        int M = Integer.valueOf(s[0]); // 用于记录id和core
        int N = Integer.valueOf(s[1]); // 用于记录指令
        IdAndCore[] idAndCores = new IdAndCore[M];
        String[] strings  = new String[N];
        for (int i = 0; i < M; i++) {
            String tempIdAndCore = in.nextLine();
            String[] split = tempIdAndCore.split(" ");
            IdAndCore idAndCore = new IdAndCore(split[0],Integer.valueOf(split[1]));
            idAndCores[i] = idAndCore;
        }

        for (int i = 0; i < N; i++) {
            strings[i] = in.nextLine();
        }

        for (int i = 0; i < N; i++) {
            System.out.print("Case "+(i+1)+": ");
            String[] s2 = strings[i].split(" ");
            if (s2[0].equals("1")){
                one(idAndCores,s2[1]);
            }else if (s2[0].equals("2")){
                two(idAndCores,s2[1]);
            }else if (s2[0].equals("3")){
                three(idAndCores,s2[1]);
            }
        }


    }

    // 类型 为 1 表示要求按分数非升序输出某个指定级别的考生的成绩，对应的 指令 则给出代表指定级别的字母；
    // * 输出格式与输入的考生信息格式相同，即 准考证号 成绩。对于分数并列的考生，按其准考证号的字典序递增输出（题目保证无重复准考证号）
    public static void one(IdAndCore[] idAndCores,String ss){
        ArrayList<IdAndCore> arrayList = new ArrayList<>();
        Arrays.sort(idAndCores,new IdAndCoreCompara());

        for (int i = 0; i < idAndCores.length; i++) {
            if (idAndCores[i].getId().substring(0,1).equals(ss)) {
                arrayList.add(idAndCores[i]);
            }
        }

        System.out.println("1 "+ss);
        for (IdAndCore idAndCore : arrayList) {
            System.out.println(idAndCore.getId()+" "+idAndCore.getCore());
        }

        if (arrayList.size()==0){
            System.out.println("NA");
        }

    }


    // 类型 为 2 表示要求将某指定考场的考生人数和总分统计输出，对应的 指令 则给出指定考场的编号；按 人数 总分 的格式输出；
    public static void two(IdAndCore[] idAndCores,String ss){

        int count = 0;
        int sum = 0;

        for (int i = 0; i < idAndCores.length; i++) {
            if (idAndCores[i].getId().substring(1,4).equals(ss)) {
                sum+=idAndCores[i].getCore();
                count++;
            }
        }

        System.out.println("2 "+ss);


        if (count==0){
            System.out.println("NA");
        }else {
            System.out.println(count+" "+sum);
        }

    }


    //类型 为 3 表示要求将某指定日期的考生人数分考场统计输出，对应的 指令 则给出指定日期，格式与准考证上日期相同。
    //  输出按人数非递增顺序，格式为 考场编号 总人数。若人数并列则按考场编号递增顺序输出。
    public static void three(IdAndCore[] idAndCores,String ss){
        HashMap<String,Integer> map = new HashMap<>();


        for (int i = 0; i < idAndCores.length; i++) {
            String tempNo = idAndCores[i].getId().substring(1,4);
            if (idAndCores[i].getId().substring(4,10).equals(ss)) {
                if (map.containsKey(tempNo)){
                    int tempI = (int)map.get(tempNo);

                    map.put(tempNo,++tempI);
                }else {
                    map.put(tempNo,1);
                }
            }
        }

        System.out.println("3 "+ss);

        Map<String,Integer> treeMap = new TreeMap(new IdAndCoreTreeMapCompare(map));
        for (Map.Entry<String, Integer> integerIntegerEntry : map.entrySet()) {
            treeMap.put(integerIntegerEntry.getKey(),integerIntegerEntry.getValue());
        }
        for (Map.Entry<String, Integer> integerIntegerEntry : treeMap.entrySet()) {
            System.out.println(integerIntegerEntry.getKey() + " " + integerIntegerEntry.getValue());
        }

        if (treeMap.size()==0){
            System.out.println("NA");
        }
    }

    // 用於treeMap,考场编号 总人数
    static class IdAndCoreTreeMapCompare implements Comparator<String>{

        Map<String,Integer> base;

        public IdAndCoreTreeMapCompare(Map<String, Integer> base) {
            this.base = base;
        }

        @Override
        public int compare(String o1, String o2) {
            if(base.get(o1)==base.get(o2)){
                return o1.compareTo(o2);
            }else {
                return -(base.get(o1)-base.get(o2));
            }

        }
    }


    // 用於one
    static class IdAndCoreCompara implements Comparator<IdAndCore> {
        @Override
        public int compare(IdAndCore o1,IdAndCore o2) {
            if (o1.getCore()== o2.getCore()){
                return o1.getId().compareTo(o2.getId());
            }else {
                return -(o1.getCore()-o2.getCore());
            }
        }
    }
    static class IdAndCore{
        private String id;
        private Integer core;

        public IdAndCore() {
        }

        public IdAndCore(String id, Integer core) {
            this.id = id;
            this.core = core;
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public Integer getCore() {
            return core;
        }

        public void setCore(Integer core) {
            this.core = core;
        }

        @Override
        public String toString() {
            return "IdAndCore{" +
                    "id='" + id + '\'' +
                    ", core=" + core +
                    '}';
        }
    }
}
